﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Reflection;
using AMS.Core.DataAccess;
using AMS.Core.Entities;
using VitCode.Castle.Entities;
using VitCode.Castle.Helper;

namespace AMS.Core.Importors
{
    public sealed class SiteImportor : AbstractImportor
    {
        private const string ADDRESS = "地址";

        private const string AREA_NAME = "所属区域名称";
        private const string CODE = "地点编码";
        private const string DEPAREMT = "所属部门";
        private const string KEY_WORD = "关键字";

        private const string m_ObjectKeyProName = "Name";

        private const string MEMO = "备注";

        private const string NAME = "地点名称";

        private const string ObjectName = "地点";
        private const string OPERATE = "操作";
        private CoreDataAccess m_Access;
        private string m_ImportType = "";
        private User m_CurrUser;
        private NameObjectDictionary m_nodAreas = new NameObjectDictionary();
        private NameObjectDictionary m_nodDepartment = new NameObjectDictionary();
        private NameObjectDictionary m_nodObjects = new NameObjectDictionary();
        private NameObjectDictionary m_nodObjectsByCode = new NameObjectDictionary();
        private NameValueCollection m_ProNameSet;
        private StringCollection m_scAreaNames = new StringCollection();
        private StringCollection m_scDepartment = new StringCollection();
        private StringCollection m_scCodes = new StringCollection();
        private StringCollection m_scNames = new StringCollection();

        public SiteImportor(string path, string sheetName, User currentUserCode, string typename)
        {
            m_ErrorMessage = new ErrorResult { TableName = "出错信息" };
            FilePath = path;
            SheetName = sheetName;
            m_IsTrans = true;
            m_CurrUser = currentUserCode;
            m_ImportType = typename;
            m_ImportNum = DataAccess.GetImportNum();
        }

        private NameValueCollection ProNameSet
        {
            get
            {
                if (m_ProNameSet == null) //简单属性绑定,用于DataRowToObject
                {
                    m_ProNameSet = new NameValueCollection();
                    m_ProNameSet.Add(CODE, "Code");
                    m_ProNameSet.Add(NAME, "Name");
                    //m_ProNameSet.Add(AREA_NAME, "Area");
                    m_ProNameSet.Add(ADDRESS, "Address");
                    m_ProNameSet.Add(KEY_WORD, "KeyWord");
                    m_ProNameSet.Add(MEMO, "Memo");
                }
                return m_ProNameSet;
            }
        }

        private CoreDataAccess DataAccess
        {
            get
            {
                if (m_Access == null)
                    m_Access = new CoreDataAccess();
                return m_Access;
            }
        }

        protected override string[] Titles
        {

            get
            {
                if (m_ImportType == "Warehouse")
                {
                    return new[] { NAME, CODE, AREA_NAME, DEPAREMT, ADDRESS, MEMO, KEY_WORD, OPERATE };
                }
                return new[] { NAME, CODE, AREA_NAME, ADDRESS, MEMO, KEY_WORD, OPERATE };
            }
        }

        protected override object DataRowToObject(DataRow row)
        {
            string strKeyVal = Convert.ToString(NAME).Trim();
            bool isInsert = (ReturnColumnValue(row, OPERATE) == INSERT);

            Site result;
            if (isInsert)
            {
                result = new Site { Name = strKeyVal, ImportNum = m_ImportNum };
                InsertCount++;
                isInsert = true;
            }
            else
            {
                result = (Site)m_nodObjects[strKeyVal];
                UpdateCount++;
            }

            for (int i = 0; i < ProNameSet.Count; i++)
            {
                string strProName = ProNameSet.Get(i);
                string strColName = ProNameSet.GetKey(i);
                if (IsNeedToUpdateInfo(isInsert, row, strColName))
                {
                    string strColValue = ReturnColumnValue(row, strColName);
                    PropertyInfo pi = result.GetType().GetProperty(strProName);
                    if (pi != null)
                    {
                        if (pi.PropertyType == typeof(String)
                            || pi.PropertyType == typeof(Int16) || pi.PropertyType == typeof(Int32) ||
                            pi.PropertyType == typeof(Int64) || pi.PropertyType == typeof(Double))
                            pi.SetValue(result, strColValue, null);
                    }
                }
            }
            if (m_ImportType == "Warehouse")
            {
                result.TypeName = "Warehouse";
                if (IsNeedToUpdateInfo(isInsert, row, DEPAREMT))
                {
                    string strDempartmentValue = ReturnColumnValue(row, DEPAREMT);
                    if (m_nodDepartment.Contains(strDempartmentValue))
                        result.Department = ((UserGroup)m_nodDepartment[strDempartmentValue]);
                }
            }
            else
            {
                result.TypeName = "House";
            }

            if (IsNeedToUpdateInfo(isInsert, row, AREA_NAME))
            {
                string strAreaNameValue = ReturnColumnValue(row, AREA_NAME);
                if (m_nodAreas.Contains(strAreaNameValue))
                    result.Area = ((Area)m_nodAreas[strAreaNameValue]);
            }
         
            return result;
        }

        protected override void SaveObjects(IList objects)
        {
            if (IsTrans)
                DataAccess.BeginTransaction();
            try
            {
                foreach (Object obj in objects)
                {
                    DataAccess.SaveOrUpdate(obj);
                }
                if (IsTrans)
                    DataAccess.Commit();
            }
            catch (Exception e)
            {
                if (m_IsTrans)
                    DataAccess.RollBack();
                throw e;
            }
            finally
            {
                if (m_IsTrans)
                    DataAccess.CloseSession();
            }
        }

        protected override void GetDBRecordSet()
        {
            try
            {
                m_nodObjects = DataAccess.GetObjectsByKeyValues("Site", m_ObjectKeyProName, m_scNames);
                m_nodObjectsByCode = DataAccess.GetObjectsByKeyValues("Site", "Code", m_scCodes);

                m_nodAreas = DataAccess.GetObjectsByKeyValues("Area", "Name", m_scAreaNames);
                m_nodDepartment = DataAccess.GetObjectsByKeyValues("UserGroup", "Name", m_scDepartment);
            }
            finally
            {
                DataAccess.CloseSession();
            }
        }

        protected override ExcelHelper CreateExcelHelper(string path, string sheetName)
        {
            var helper = new ExcelHelper(path, sheetName);
            helper.NotRepleateColumns.AddColumnByName(NAME);
            helper.NotEmptyColumns.AddColumnByName(OPERATE);
            return helper;
        }

        protected override void CreateDBSearchCondition(DataRow row, ErrorResult errorResult, int excelRowNumber)
        {
            string Message = "";
            string code = ReturnColumnValue(row, CODE);
            string strObjKeyVal = ReturnColumnValue(row, NAME);


            string operate = Convert.ToString(row[OPERATE]).Trim();

            bool isInsert = (operate == INSERT);

            //控制非空字段的导入与更新操作
            if (m_ImportType == "Warehouse")
            {
                var insertNoEmptyTitles =
                    new[]
                    {
                        NAME, CODE, AREA_NAME,DEPAREMT
                    };
                CheckInsertNoEmptyColumn(row, insertNoEmptyTitles, isInsert, errorResult, excelRowNumber);
            }
            else
            {
                var insertNoEmptyTitles =
                    new[]
                    {
                        NAME, CODE, AREA_NAME
                    };
                CheckInsertNoEmptyColumn(row, insertNoEmptyTitles, isInsert, errorResult, excelRowNumber);
            }




            //不允许清除内容的列
            if (m_ImportType == "Warehouse")
            {
                var updateNoDeleteTitles = new[]
                                           {
                                               NAME, CODE, AREA_NAME,DEPAREMT
                                           };

                CheckUpdateNoDeleteField(row, updateNoDeleteTitles, isInsert, errorResult, excelRowNumber);
            }
            else
            {
                var updateNoDeleteTitles = new[]
                                           {
                                               NAME, CODE, AREA_NAME
                                           };

                CheckUpdateNoDeleteField(row, updateNoDeleteTitles, isInsert, errorResult, excelRowNumber);
            }
          


            if (!CheckFieldLength(row, NAME, 1, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            else if (!m_scNames.Contains(strObjKeyVal))
                m_scNames.Add(strObjKeyVal);

            if (!CheckFieldLength(row, CODE, 1, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            else if (!m_scNames.Contains(code))
                m_scNames.Add(code);

            string strAreaName = ReturnColumnValue(row, AREA_NAME);
            if (!CheckFieldLength(row, AREA_NAME, 0, 50, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
            if (IsNeedToUpdateInfo(isInsert, strAreaName) && strAreaName.Length > 0 &&
                !m_scAreaNames.Contains(strAreaName))
                m_scAreaNames.Add(strAreaName);

            if (m_ImportType == "Warehouse")
            {
                string strDepartment = ReturnColumnValue(row, DEPAREMT);
                if (!CheckFieldLength(row, DEPAREMT, 0, 50, out Message))
                    errorResult.SetMessage(excelRowNumber, Message);
                if (IsNeedToUpdateInfo(isInsert, strDepartment) && strDepartment.Length > 0 &&
                    !m_scDepartment.Contains(strDepartment))
                    m_scDepartment.Add(strDepartment);
            }
            if (!CheckFieldLength(row, ADDRESS, 0, 200, out Message))
                errorResult.SetMessage(excelRowNumber, Message);

            if (!CheckFieldLength(row, MEMO, 0, 500, out Message))
                errorResult.SetMessage(excelRowNumber, Message);

            if (!CheckFieldLength(row, KEY_WORD, 0, 100, out Message))
                errorResult.SetMessage(excelRowNumber, Message);
        }

        protected override void CheckInDb(DataRow row, int excelRowNumber, ErrorResult errorResult)
        {
            bool isInsert = (ReturnColumnValue(row, OPERATE) == INSERT);
            string msg = "";
            string strObjKeyProVal = ReturnColumnValue(row, NAME);
            string strCode = ReturnColumnValue(row, CODE);

            if (isInsert)
            {
                if (CheckChildObjectExists(m_nodObjects, strObjKeyProVal, NAME, out msg))
                    errorResult.SetMessage(excelRowNumber,
                                           NAME + "为: [ " + strObjKeyProVal + " ] 的" + ObjectName +
                                           "已经存在不能导入");
                if (CheckChildObjectExists(m_nodObjectsByCode, strCode, CODE, out msg))
                    errorResult.SetMessage(excelRowNumber, CODE + "为: [ " + strCode + " ] 的" + ObjectName + "已经存在不能导入");
            }
            else
            {
                if (!CheckChildObjectExists(m_nodObjects, strObjKeyProVal, NAME, out msg))
                    errorResult.SetMessage(excelRowNumber,
                                           NAME + "为: [ " + strObjKeyProVal + " ] 的" + ObjectName +
                                           "不存在不能更新");
                if (m_nodObjectsByCode.Contains(strCode))
                {
                    var objByCode = (Site)(m_nodObjectsByCode[strCode]);
                    if (!objByCode.Name.Equals(strObjKeyProVal) && objByCode.Code.Equals(strCode))
                        errorResult.SetMessage(excelRowNumber,
                                               CODE + "为:'" + strCode + "'的已被其它的'" + ObjectName + "'占用(" +
                                               NAME + "为:'" + strObjKeyProVal + "'的" + ObjectName + "对象)");
                }
            }


            if (!CheckChildObjectExists(m_nodAreas, row, AREA_NAME, out msg))
                errorResult.SetMessage(excelRowNumber, msg);
            if (m_ImportType == "Warehouse")
             if (!CheckChildObjectExists(m_nodDepartment, row, DEPAREMT, out msg))
                errorResult.SetMessage(excelRowNumber, msg);
        }
    }
}